var wsclient = (function() {

    var ws = null;
    var wsURI = 'ws://' + location.host  + '/websockets/chat';			//agrega a la url

    function connect(nombreUsuario) {		
        if(!nombreUsuario || nombreUsuario == '') {								//verifica que no sea null
            return;
        }

        if ('WebSocket' in window) {
            ws = new WebSocket(wsURI + '?userName=' + nombreUsuario);		//instancia un web socket en chrome
        } else if ('MozWebSocket' in window) {
            ws = new MozWebSocket(wsURI + '?userName=' + nombreUsuario);		//instancia un web socket en mozilla	
            
        } else {														//no soporta el navegador
            alert('Tu navegador no soporta WebSockets');
            return;
        }
        ws.onopen = function () {										//manejador que es invocado cuando se abre una conexión con el servidor.
            establecerConeccion(true);
        };
        ws.onmessage = function (event) {								//manejador que es invocado cuando llega un mensaje desde el servidor
            var mensaje = JSON.parse(event.data);						//obtiene el mensaje
            procesarMensaje(mensaje);
        };

        ws.onclose = function () {
            establecerConeccion(false);
            document.getElementById('userName').value = '';
            cerrarConversaciones();
        };
		
			 //~ messageInfo :
			//~ {
				//~ from : 'Miguel Arlandy',
				//~ to : 'Iker Casillas',
				//~ message : 'Iker eres el mejor!!!'
			//~ }
        function procesarMensaje(mensaje) {
            if (mensaje.messageInfo) {
                mostrarConversacion(mensaje.messageInfo.from);
                agregarMensaje(mensaje.messageInfo.from, mensaje.messageInfo.message, removerEspacio(mensaje.messageInfo.from) + 'conversation');
            } else if (mensaje.statusInfo) {
                if (mensaje.statusInfo.status == 'CONNECTED') {
                    agregarUsuarioEnLinea(mensaje.statusInfo.user);
                } else if (mensaje.statusInfo.status == 'DISCONNECTED') {
                    removerUsuarioEnLinea(mensaje.statusInfo.user);
                }
            } else if (mensaje.connectionInfo) {
                var usuariosActivos = mensaje.connectionInfo.activeUsers;
                for (var i=0; i<usuariosActivos.length; i++) {
                    agregarUsuarioEnLinea(usuariosActivos[i]);
                }
            }
        }


    }

    function disconnect() {
        if (ws != null) {
            ws.close();
            ws = null;
        }
        establecerConeccion(false);
    }

    function establecerConeccion(conectado) {
        document.getElementById('connect').disabled = conectado;			//no te habilita el conectado
        document.getElementById('disconnect').disabled = !conectado;		//no te habilita el desconectado
        vaciarListaUsuariosConectados();												//limpia el vector de conectados
        if (conectado) {
            actualizarUsuarioConectado();											//actualiza los conectados si true
        } else {
            actualizarUsuarioDesconectado();									
        }
    }

    function actualizarUsuarioConectado() {
        var usuarioLogueado = $('#userName');									//#variable
        var usuarioEnLinea = $('.onLineUserName');							//clase
        usuarioEnLinea.html(usuarioLogueado.val());							//saca el valor del html
        usuarioLogueado.css({display:'none'});								//no permite escribir un nuevo nombre desabilita el text
        usuarioEnLinea.css({visibility:'visible'});							//muestra los usuarios conectados
        $('#status').html('Conectado');
        $('#status').attr({class : 'connected'});
        $('#onLineUsersPanel').css({visibility:'visible'});
    }

    function actualizarUsuarioDesconectado() {
        $('.onLineUserName').css({visibility:'hidden'});					//oculta la lista de conectados
        $('#userName').css({display:''});
        $('#status').html('Desconectado');									//cambia de estado
        $('#status').attr({class : 'disconnected'});
        $('#onLineUsersPanel').css({visibility:'hidden'});
    }

    function vaciarListaUsuariosConectados() {
        $('#onlineUsers').html('');
    }

    function removerTab(idConversacion) {
        $('#conversations').tabs('remove', idConversacion);
    }

    function removerEspacio(text) {
        return text.replace(/\s/g,"_");
    }

    function mostrarConversacion(emisor) {
        var conversaciones = $('#conversations');						//obtiene un tab
        conversaciones.css({visibility:'visible'});						//hace visible el tab
        var idConversacion = removerEspacio(emisor) + 'conversation';	//
        if(document.getElementById(idConversacion) == null) {
            crearPanelDeConversacion(emisor);
            conversaciones.tabs('add', '#' + idConversacion, emisor);
        }
        conversaciones.tabs('select', '#' + idConversacion);
        $('#'+idConversacion+'message').focus();
    }

    function crearPanelDeConversacion(nombre) {
        var idConversacion = removerEspacio(nombre) + 'conversation';
        var PanelDeConversacion = $(document.createElement('div'));
        PanelDeConversacion.attr({id : idConversacion, class : 'conversation'});
        $('<p class="messages"></p><textarea id="' + idConversacion + 'message"></textarea>').appendTo(PanelDeConversacion);
        var sendButton = creatBotonEnviar(nombre);
        sendButton.appendTo(PanelDeConversacion);
        var closeButton = crearBotonCerrar(removerEspacio(nombre));
        closeButton.appendTo(PanelDeConversacion);
        PanelDeConversacion.appendTo($('#conversations'));
    }

    function creatBotonEnviar(nombre) {
        var idConversacion = removerEspacio(nombre) + 'conversation';
        var boton = $(document.createElement('button'));
        boton.html('Enviar');
        boton.click(function () {
            var emisor = document.getElementById('userName').value;
            var mensaje = document.getElementById(idConversacion+'message').value;
            enviarAlChat(emisor, nombre, mensaje);
            agregarMensaje(emisor, mensaje, idConversacion);
            document.getElementById(idConversacion+'message').value = '';
        });
        return boton;
    }

    function cerrarConversaciones() {
        for (var i = $('#conversations').tabs('length'); i >= 0; i--) {
            $('#conversations').tabs('remove', i-1);
        }
        $('#conversations').css({visibility : 'hidden'});
    }

    function crearBotonCerrar(idConversacion) {
        var boton = $(document.createElement('button'));
        boton.html('Cerrar');
        boton.click(function () {
            removerTab(idConversacion);
        });
        return boton;
    }

    function agregarMensaje (emisor, mensaje, conversationPanelId) {
        var mensajes = $('#' + conversationPanelId + ' .messages');
        $('<div class="message"><span><b>' + emisor + '</b> dice:</span><p>' + $('<p/>').text(mensaje).html() + '</p></div>').appendTo(mensajes);
        mensajes.scrollTop(mensajes[0].scrollHeight);
        $('#'+conversationPanelId+' textarea').focus();
    }

    function enviarAlChat(emisor, receptor, mensaje) {
        ws.send(JSON.stringify({messageInfo : {from : emisor, to : receptor, message : mensaje}}));
    }

    /********* usuarios conectados *******/
    function agregarUsuarioEnLinea(nombreUsuario) {
        var nuevoUsuarioEnLinea = crearUsuarioEnLinea(nombreUsuario);
        nuevoUsuarioEnLinea.appendTo($('#onlineUsers'));
    }

    function removerUsuarioEnLinea(nombreUsuario) {
        $('#onlineUsers > li').each(function (index, elem) {
            if (elem.id == nombreUsuario + 'onlineuser') {
                $(elem).remove();
            }
        });
    }

    function crearUsuarioEnLinea(nombreUsuario) {
        var link = $(document.createElement('a'));
        link.html(nombreUsuario);
        link.click(function(){
            mostrarConversacion(nombreUsuario);
        });
        var lista = $(document.createElement('li'));
        lista.attr({id : (nombreUsuario + 'onlineuser')});
        link.appendTo(lista);
        return lista;
    }

    // metodos publicos
    return {
        connect : connect,
        disconnect : disconnect
    };
})();
